From: awilliam@xenbuild2.aw Date: Thu, 11 Jan 2007 21:27:39 +0000 (-0700) Subject: [IA64] Can't inject event, when guest is executing rfi X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15413 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22%22/%22http:/www.example.com/cgi/%22https:/%22%22?a=commitdiff_plain;h=2293be461e7fbd877b44c565748b8cc2885117be;p=xen.git [IA64] Can't inject event, when guest is executing rfi Can't inject event, when guest is executing rfi, and both both PSCB(v, ifs) and regs->ifs are valid It's very rare case, but I did catch it. It caused domain0 crash Signed-off-by: Anthony Xu --- diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c index 8893c7395f..454bdd69a6 100644 --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -134,6 +134,11 @@ void reflect_event(struct pt_regs *regs) if (!event_pending(v)) return; + // can't inject event, when XEN is emulating rfi + // and both PSCB(v, ifs) and regs->ifs are valid + if (regs->cr_iip == *(unsigned long *)dorfirfi) + return; + if (!PSCB(v, interrupt_collection_enabled)) printk("psr.ic off, delivering event, ipsr=%lx,iip=%lx," "isr=%lx,viip=0x%lx\n", diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index 8adad97c21..10a8227ef7 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -1326,7 +1326,6 @@ IA64FAULT vcpu_rfi(VCPU * vcpu) u64 int_enable, regspsr = 0; u64 ifs; REGS *regs = vcpu_regs(vcpu); - extern void dorfirfi(void); psr.i64 = PSCB(vcpu, ipsr); if (psr.ia64_psr.cpl < 3) @@ -1350,18 +1349,24 @@ IA64FAULT vcpu_rfi(VCPU * vcpu) return IA64_ILLOP_FAULT; } PSCB(vcpu, incomplete_regframe) = 0; // is this necessary? + ifs = PSCB(vcpu, ifs); - //if ((ifs & regs->cr_ifs & 0x8000000000000000L) && ifs != regs->cr_ifs) { - //if ((ifs & 0x8000000000000000L) && ifs != regs->cr_ifs) { - if (ifs & regs->cr_ifs & 0x8000000000000000L) { - // TODO: validate PSCB(vcpu,iip) - // TODO: PSCB(vcpu,ipsr) = psr; - PSCB(vcpu, ipsr) = psr.i64; - // now set up the trampoline - regs->cr_iip = *(unsigned long *)dorfirfi; // function pointer!! - __asm__ __volatile("mov %0=psr;;":"=r"(regspsr)::"memory"); - regs->cr_ipsr = - regspsr & ~(IA64_PSR_I | IA64_PSR_IC | IA64_PSR_BN); + if (ifs > 0x8000000000000000UL) { + if (regs->cr_ifs > 0x8000000000000000UL) { + // TODO: validate PSCB(vcpu,iip) + // TODO: PSCB(vcpu,ipsr) = psr; + PSCB(vcpu, ipsr) = psr.i64; + // now set up the trampoline + regs->cr_iip = *(unsigned long *)dorfirfi; // func ptr! + __asm__ __volatile("mov %0=psr;;":"=r"(regspsr) + ::"memory"); + regs->cr_ipsr = regspsr & ~(IA64_PSR_I | IA64_PSR_IC | + IA64_PSR_BN); + } else { + regs->cr_ifs = ifs; + regs->cr_ipsr = psr.i64; + regs->cr_iip = PSCB(vcpu, iip); + } } else { regs->cr_ipsr = psr.i64; regs->cr_iip = PSCB(vcpu, iip); diff --git a/xen/include/asm-ia64/vcpu.h b/xen/include/asm-ia64/vcpu.h index b61915e3b2..e403213d65 100644 --- a/xen/include/asm-ia64/vcpu.h +++ b/xen/include/asm-ia64/vcpu.h @@ -23,6 +23,8 @@ extern u64 cycle_to_ns(u64 cycle); #define SPURIOUS_VECTOR 0xf +extern void dorfirfi(void); + /* general registers */ extern u64 vcpu_get_gr(VCPU * vcpu, unsigned long reg); extern IA64FAULT vcpu_get_gr_nat(VCPU * vcpu, unsigned long reg, u64 * val);